package org.catspaw.cherubim.security.ss3.rbac;

import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.access.intercept.RequestKey;

import org.catspaw.cherubim.security.rbac.Resource;
import org.catspaw.cherubim.security.rbac.Permission;
import org.catspaw.cherubim.security.rbac.Role;
import org.catspaw.cherubim.security.rbac.dao.ResourceDao;
import org.catspaw.cherubim.security.rbac.dao.PermissionDao;
import org.catspaw.cherubim.security.rbac.dao.RoleDao;

public class RoleBasedRequestMapFactoryBean implements
		FactoryBean<LinkedHashMap<RequestKey, Collection<ConfigAttribute>>> {

	private PermissionDao	permissionDao;
	private ResourceDao		resourceDao;
	private RoleDao			roleDao;

	public LinkedHashMap<RequestKey, Collection<ConfigAttribute>> getObject()
			throws Exception {
		LinkedHashMap<RequestKey, Collection<ConfigAttribute>> map = new LinkedHashMap<RequestKey, Collection<ConfigAttribute>>();
		List<? extends Resource> resources = resourceDao.findAll();
		for (Resource resource : resources) {
			Set<ConfigAttribute> attributes = new HashSet<ConfigAttribute>();
			String urlCode = resource.getCode();
			List<? extends Permission> permissions = permissionDao
					.findByDomainCode(urlCode);
			for (Permission permission : permissions) {
				List<? extends Role> roles = roleDao
						.findByPermissionCode(permission.getCode());
				for (Role role : roles) {
					ConfigAttribute attribute = new SecurityConfig(role
							.getCode());
					attributes.add(attribute);
				}
			}
			//TODO 以role code为key
			RequestKey key = new RequestKey(resource.getResourceString());
			map.put(key, attributes);
		}
		return map;
	}

	public Class<?> getObjectType() {
		return LinkedHashMap.class;
	}

	public boolean isSingleton() {
		return true;
	}

	public PermissionDao getPermissionDao() {
		return permissionDao;
	}

	public ResourceDao getResourceDao() {
		return resourceDao;
	}

	public RoleDao getRoleDao() {
		return roleDao;
	}

	public void setPermissionDao(PermissionDao permissionDao) {
		this.permissionDao = permissionDao;
	}

	public void setResourceDao(ResourceDao resourceDao) {
		this.resourceDao = resourceDao;
	}

	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}
}
